/*
 * Copyright 2010 Pierre-Yves Ricau
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.excilys.capiq.client.view;

import java.util.ArrayList;
import java.util.List;

import com.excilys.capiq.client.service.QuestionServiceAsync;
import com.excilys.capiq.shared.AnswerDTO;
import com.excilys.capiq.shared.QuestionDTO;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.Widget;

public class AnswerQuestionWidget extends Composite {

	interface AnswerQuestionBinder extends UiBinder<Widget, AnswerQuestionWidget> {}

	private static AnswerQuestionBinder	uiBinder			= GWT.create(AnswerQuestionBinder.class);

	@UiField
	Label								question;

	@UiField
	Label								explanation;

	@UiField
	FlowPanel							answersPanel;

	@UiField
	Button								answer;

	@UiField
	InlineLabel							author;

	@UiField
	Anchor								next;

	private List<RadioButton>			answerRadioButtons	= new ArrayList<RadioButton>();

	private QuestionDTO					questionDto;

	private final QuestionServiceAsync	questionService;

	public AnswerQuestionWidget(QuestionServiceAsync questionService) {
		this.questionService = questionService;
		initWidget(uiBinder.createAndBindUi(this));
		nextQuestion();
	}

	private void nextQuestion() {
		answer.setVisible(false);
		next.setVisible(false);
		explanation.setVisible(false);
		answersPanel.clear();
		answerRadioButtons.clear();
		question.setText("Chargement...");

		questionService.getQuestion(new AsyncCallback<QuestionDTO>() {

			@Override
			public void onSuccess(QuestionDTO result) {

				questionDto = result;

				if (result == null) {
					question.setText("Plus de question disponibles, pourquoi ne pas en créer de nouvelles ?");
					answer.setVisible(false);
					next.setVisible(true);
					return;
				}

				author.setText(result.getAuthor());
				question.setText(result.getQuestion());

				for (String answer : result.getAnswers()) {
					FlowPanel answerPanel = new FlowPanel();
					RadioButton answerRadioButton = new RadioButton("answerButtons");
					InlineLabel answerText = new InlineLabel(answer);

					answerRadioButtons.add(answerRadioButton);

					answerPanel.add(answerRadioButton);
					answerPanel.add(answerText);

					answersPanel.add(answerPanel);
				}

				answer.setVisible(true);
				next.setVisible(false);
			}

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Erreur " + caught.getMessage());
			}
		});
	}

	@UiHandler("answer")
	public void answer(ClickEvent event) {

		if (questionDto == null) {
			Window.alert("Aucune question chargée");
			return;
		}

		int selectedAnswerIndex = -1;
		for (int i = 0; i < answerRadioButtons.size(); i++) {
			if (answerRadioButtons.get(i).getValue()) {
				selectedAnswerIndex = i;
				break;
			}
		}
		if (selectedAnswerIndex == -1) {
			Window.alert("Faut sélectionner une réponse, hé cong !");
			return;
		}

		final int sentAnswerIndex = selectedAnswerIndex;

		answer.setVisible(false);

		final DialogBox dialog = new DialogBox();

		FlowPanel dialogPanel = new FlowPanel();

		dialog.setText("Cette question est-elle intéressante ?");
		Button dialogYes = new Button("Oui");
		Button dialogNo = new Button("Non");

		dialogYes.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				dialog.hide();
				dialog.removeFromParent();
				questionFullyAnswered(sentAnswerIndex, true);
			}
		});

		dialogNo.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				dialog.hide();
				dialog.removeFromParent();
				questionFullyAnswered(sentAnswerIndex, false);
			}
		});

		dialogPanel.add(dialogYes);
		dialogPanel.add(dialogNo);
		dialog.setWidget(dialogPanel);

		dialog.setGlassEnabled(true);

		dialog.center();

	}

	private void questionFullyAnswered(final int selectedAnswerIndex, boolean goodQuestion) {

		String selectedAnswer = questionDto.getAnswers().get(selectedAnswerIndex);

		questionService.answerQuestion(questionDto.getId(), selectedAnswer, goodQuestion, new AsyncCallback<AnswerDTO>() {
			@Override
			public void onSuccess(AnswerDTO answerDto) {

				int goodAnswerIndex = questionDto.getAnswers().indexOf(answerDto.getGoodAnswer());

				String explanationValue = answerDto.getExplanation();

				if (explanationValue == null) {
					explanation.setText("Aucune explication donnée par l'auteur");
				} else {
					explanation.setText("Explication : " + explanationValue);
				}

				explanation.setVisible(true);

				FlowPanel answerPanel = (FlowPanel) answerRadioButtons.get(goodAnswerIndex).getParent();

				if (goodAnswerIndex == selectedAnswerIndex) {
					answerPanel.addStyleName("goodAnswer");
				} else {
					answerPanel.addStyleName("badAnswer");
				}
				next.setVisible(true);
			}

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Erreur " + caught.getMessage());
				next.setVisible(true);
			}
		});
	}

	@UiHandler("next")
	public void next(ClickEvent event) {
		nextQuestion();
	}

}
